package com.xishu.controller;

import com.xishu.annotation.valid.MethodValidator;
import com.xishu.client.PrinterClient;
import com.xishu.entity.hardware.Printer;
import com.xishu.entity.shop.Shop;
import com.xishu.response.ResponseData;
import com.xishu.response.ResponseStatus;
import com.xishu.response.VerifyUtil;
import com.xishu.service.CommonService;
import com.xishu.service.ShopService;
import com.xishu.service.print.PrinterService;
import com.xishu.util.AES;
import com.xishu.util.Tools;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import net.sf.json.JSONObject;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.bind.annotation.*;

import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;


@RestController
@Api(description = "打印机")
public class PrinterController implements Tools {
    private static Logger logger = LoggerFactory.getLogger(PrinterController.class);
    private CommonService commonService = CommonService.getInstance();
    private ShopService shopService = ShopService.getInstance();
    private PrinterClient printerClient = PrinterClient.getInstance();


    @ApiOperation(value = "添加打印机配置")
    @PostMapping(value = ("/printer"), produces = ("application/json;charset=UTF-8"))
    @MethodValidator(checkShop = true, checkShopId = true)
    public ResponseData create(@RequestBody Printer printer) throws Exception {
        Long shopId = printer.getShopId();
        VerifyUtil.verify(() -> shopId != null);
        VerifyUtil.verify(() -> isNotEmpty(printer.getPrinterSn()) && isNotEmpty(printer.getPrinterKey())
                && isNotEmpty(printer.getLocation()) && isNotEmpty(printer.getName()));
        Shop shop = shopService.findShopById(shopId);
        VerifyUtil.verify(() -> shop != null);

        //检查标签
        PrinterService.getInstance().checkPrinterLabelValid(shopId, null, printer.getPrinterLabelList());

        String printerSn = printer.getPrinterSn();
        String printerKey = printer.getPrinterKey();
        String location = printer.getLocation();

        //配置加密保存
        printer.setPrinterSn(AES.encrypt(printer.getPrinterSn()));
        printer.setPrinterKey(AES.encrypt(printer.getPrinterKey()));

        logger.info("will add printer, printer sn is {}, key is {}", printerSn, printerKey);
        String addResult = printerClient.addPrinter(printerSn, printerKey, location);
        logger.info("addResult is {}", addResult);
        JSONObject addResultJson = JSONObject.fromObject(addResult);
        int status = addResultJson.getInt("ret");
        VerifyUtil.verify(() -> status == 0, ResponseStatus.PRINTER_CONFIG_ERROR);

        if (getBoolean(printer.getPrintPayedOrder())) {
            PrinterService.getInstance().setOtherPrinterNotPrinterPayedOrderInC(shopId);
        }

        //配置正确后，再添加到数据库
        return commonService.createObject(printer, (p) -> {
            PrinterService.getInstance().setOtherPrinterInCFalse(p);
        });
    }

    @ApiOperation(value = "查询打印机配置")
    @PutMapping(value = ("/printer"), produces = ("application/json;charset=UTF-8"))
    public ResponseData search(@RequestBody Printer printer) throws Exception {
        CommonService commonService = CommonService.getInstance();
        return commonService.searchResponse(printer, p -> {
            if (p.getPacking() == null) {
                p.setPacking(false);
            }

            //打印机编号显示,解密显示
            if (isNotEmpty(p.getPrinterSn())) {
                p.setPrinterSn(AES.decrypt(p.getPrinterSn()));
            }

            try {
                Long shopId = p.getShopId();
                Shop shop = ShopService.getInstance().findShopById(shopId);
                p.setShopName_zh(shop.getName_zh());
                p.setShopName_en(shop.getName_en());
            } catch (Exception e) {
                logger.error("e", e);
            }
        });
    }

    @ApiOperation(value = "修改打印机配置")
    @PutMapping(value = ("/printer/modify"), produces = ("application/json;charset=UTF-8"))
    public ResponseData modify(@RequestBody Printer printer) throws Exception {
        PrinterService.getInstance().clearDefaultSn(printer);

        if (isNotEmpty(printer.getPrinterSn())) {
            printer.setPrinterSn(AES.encrypt(printer.getPrinterSn()));
        }

        if (isNotEmpty(printer.getPrinterKey())) {
            printer.setPrinterKey(AES.encrypt(printer.getPrinterKey()));
        }

        if (isNotEmpty(printer.getPrinterSn()) || isNotEmpty(printer.getPrinterSn())) {
            Printer printerInDb = commonService.findEntity(printer.getId(), Printer.class);
            logger.info("will add printer, printer sn is {}, key is {}", printerInDb.getPrinterSn(), printerInDb.getPrinterKey());
            String addResult = printerClient.addPrinter(printerInDb.getPrinterSn(), printerInDb.getPrinterKey(), printerInDb.getLocation());
            logger.info("addResult is {}", addResult);
            JSONObject addResultJson = JSONObject.fromObject(addResult);
            int status = addResultJson.getInt("ret");
            VerifyUtil.verify(() -> status == 0, ResponseStatus.PRINTER_CONFIG_ERROR);
        }

        //如果修改成了厨房打印机,那么将标签删除掉
        if (equals(printer.getLocation(), "barCounter")) {
            printer.setPrinterLabelList(new ArrayList<>());
        }

        if (getBoolean(printer.getPrintPayedOrder())) {
            Printer printerInDb = commonService.findEntity(printer.getId(), Printer.class);
            PrinterService.getInstance().setOtherPrinterNotPrinterPayedOrderInC(printerInDb.getShopId());
        }

        return commonService.updateObject(printer, (p1) -> {
            try {
                //修改了打印标签，需要校验
                if (printer.getPrinterLabelList() != null) {
                    Printer printerInDb = commonService.findEntity(printer.getId(), Printer.class);
                    //刷新一次打印机，打印机服务器返回打印机的状态是在线的时候才返回
                    printerClient.flushPrinterStatus(printerInDb);
                }

                PrinterService.getInstance().setOtherPrinterInCFalse(p1);
            } catch (Exception e) {
                logger.error("e", e);
            }
        });
    }

    @ApiOperation(value = "刷新打印机的状态, 只用传shopId")
    @PutMapping(value = ("/printer/status"), produces = ("application/json;charset=UTF-8"))
    @MethodValidator(checkShop = true)
    public ResponseData queryStatus(@RequestBody Printer reqPrinter) throws Exception {
        //传shopId过来
        Long shopId = reqPrinter.getShopId();
        VerifyUtil.verify(() -> shopId != null);

        List<Printer> allShopPrinters = PrinterService.getInstance().flushPrinterStatus(shopId);
        //过滤在线的打印机
        allShopPrinters = allShopPrinters.stream().filter(p -> getBoolean(p.getOnline())).collect(Collectors.toList());
        return commonService.createResponse(allShopPrinters);
    }

    @ApiOperation(value = "删除打印机")
    @DeleteMapping(value = ("/printer"), produces = ("application/json;charset=UTF-8"))
    @MethodValidator(checkShop = true)
    public ResponseData delete(@RequestBody Printer reqPrinter) throws Exception {
        return commonService.delete(reqPrinter);
    }
}
